/**
 * @file data_fusion.h
 * @brief 数据融合模块，处理多源覆冰数据
 * @version 2.0
 * @date 2023-12-10
 */

#ifndef DATA_FUSION_H
#define DATA_FUSION_H

#include <stdint.h>
#include <stdbool.h>
#include "common_defs.h"      // 包含 FusionData, SensorData 定义
#include "uart_protocol.h"    // 包含 SensorDataPacket 定义
#include "ice_calculation.h"  // 包含 CableParameters 定义
#include "visual_monitor.h"   // 包含 VisualIceData 定义
#include "stereo_monitor.h"   // 包含 StereoData 定义

// 数据源可用性标志位
#define SENSOR_DATA_AVAILABLE  0x01
#define VISUAL_DATA_AVAILABLE  0x02
#define STEREO_DATA_AVAILABLE  0x04
#define WEATHER_DATA_AVAILABLE 0x08

// 注意：风速阈值常量在 app_control.h 中定义为 extern const float
// 这里不再重复定义 HIGH_WIND_THRESHOLD 和 EXTREME_WIND_THRESHOLD

// 数据质量等级
typedef enum {
    DATA_QUALITY_INVALID = 0,   // 无效
    DATA_QUALITY_LOW,           // 低质量
    DATA_QUALITY_MEDIUM,        // 中等质量
    DATA_QUALITY_HIGH,          // 高质量
    DATA_QUALITY_EXCELLENT      // 极高质量
} DataQuality;

// 扩展的融合数据结构
typedef struct {
    FusionData base;                    // 基础融合数据
    float fusion_confidence;            // 融合置信度 (0.0-1.0)
    float raw_thickness;                // 原始厚度（未滤波）
    float sensor_weight;                // 传感器数据权重
    float visual_weight;                // 视觉数据权重
    float stereo_weight;                // 立体视觉数据权重
    bool is_filtered;                   // 是否已应用滤波
    bool has_anomaly;                   // 是否存在异常
    uint8_t anomaly_flags;              // 异常标志位
    DataQuality ice_data_quality;       // 冰数据质量
    DataQuality weather_data_quality;   // 气象数据质量
} ExtendedFusionData;

// 数据源质量评估结构
typedef struct {
    DataQuality quality;         // 质量等级
    float confidence;            // 置信度 (0.0-1.0)
    uint64_t last_update_time;   // 最后更新时间
    float stability;             // 稳定性指标 (0.0-1.0)
    float variance;              // 数据方差
    int consecutive_valid;       // 连续有效计数
    int consecutive_invalid;     // 连续无效计数
} DataSourceQuality;

// 卡尔曼滤波器结构
typedef struct {
    float x;           // 状态估计
    float P;           // 估计协方差
    float Q;           // 过程噪声协方差
    float R;           // 测量噪声协方差
    float K;           // 卡尔曼增益
    bool initialized;  // 初始化标志
} KalmanFilter;

/**
 * @brief 初始化数据融合模块
 * 
 * @return int 成功返回0，失败返回非0值
 */
int init_data_fusion(void);

/**
 * @brief 重置数据融合状态
 * 
 * @return int 成功返回0，失败返回非0值
 */
int reset_data_fusion(void);

/**
 * @brief 设置数据融合参数
 * 
 * @param process_noise 过程噪声协方差
 * @param measurement_noise 测量噪声协方差
 * @param anomaly_threshold 异常检测阈值
 * @return int 成功返回0，失败返回非0值
 */
int set_fusion_parameters(float process_noise, float measurement_noise, float anomaly_threshold);

/**
 * @brief 清理数据融合模块资源
 */
void cleanup_data_fusion(void);

/**
 * @brief 获取数据质量等级描述文本
 * 
 * @param quality 数据质量枚举值
 * @return const char* 质量描述文本
 */
const char* get_data_quality_description(DataQuality quality);

/**
 * @brief 根据传感器拉力数据处理计算拉力相关参数
 * 
 * @param tension1 传感器1拉力值(N)
 * @param tension2 传感器2拉力值(N)
 * @param wind_speed 风速(m/s)
 * @param wind_direction 风向(度)
 * @param tension_no_ice 无冰状态下的拉力值(N)
 * @param out_avg_tension 输出平均拉力值(N)
 * @param out_tension_increase 输出拉力增加量(N)
 * @return bool 是否有覆冰(true表示有)
 */
bool process_tension_data(float tension1, float tension2, 
                        float wind_speed, float wind_direction,
                        float tension_no_ice,
                        float *out_avg_tension, float *out_tension_increase);

/**
 * @brief 融合传感器和视觉数据以计算等值线缆覆冰厚度
 * 
 * @param sensor_thickness 传感器计算的厚度(mm)
 * @param visual_thickness 视觉计算的厚度(mm)
 * @param temperature 环境温度(°C)
 * @param humidity 相对湿度(%)
 * @param wind_speed 风速(m/s)
 * @param wind_direction 风向(度)
 * @param use_correction 是否使用环境修正
 * @return float 融合后的覆冰厚度(mm)
 */
float fuse_equivalent_cable_data(float sensor_thickness, float visual_thickness,
                               float temperature, float humidity,
                               float wind_speed, float wind_direction,
                               bool use_correction);

/**
 * @brief 融合传感器和双目视觉数据以计算真实线缆覆冰厚度
 * 
 * @param stereo_thickness 立体视觉厚度(mm)
 * @param sensor_available 是否有传感器数据
 * @param temperature 环境温度(°C)
 * @param humidity 相对湿度(%)
 * @param wind_speed 风速(m/s)
 * @param wind_direction 风向(度)
 * @return float 融合后的覆冰厚度(mm)
 */
float fuse_real_cable_data(float stereo_thickness, bool sensor_available,
                         float temperature, float humidity,
                         float wind_speed, float wind_direction);

/**
 * @brief 根据多源数据计算覆冰厚度
 * 
 * @param sensor_data 传感器数据包指针，可为NULL
 * @param visual_data 视觉数据指针，可为NULL
 * @param stereo_data 立体视觉数据指针，可为NULL
 * @param available_data 可用数据源标志位
 * @param cable_params 线缆参数指针
 * @param run_mode 运行模式
 * @param fusion_result 融合结果输出
 * @return bool 成功返回true，失败返回false
 */
bool fuse_all_data(
    const SensorDataPacket *sensor_data,
    const VisualIceData *visual_data,
    const StereoData *stereo_data,
    int available_data,
    const CableParameters *cable_params,
    RunMode run_mode,
    FusionData *fusion_result
);

/**
 * @brief 根据多源数据计算覆冰厚度和扩展信息
 * 
 * @param sensor_data 传感器数据包指针，可为NULL
 * @param visual_data 视觉数据指针，可为NULL
 * @param stereo_data 立体视觉数据指针，可为NULL
 * @param available_data 可用数据源标志位
 * @param cable_params 线缆参数指针
 * @param run_mode 运行模式
 * @param fusion_result 基础融合结果输出
 * @param extended_result 扩展融合结果输出，可为NULL
 * @return bool 成功返回true，失败返回false
 */
bool fuse_all_data_extended(
    const SensorDataPacket *sensor_data,
    const VisualIceData *visual_data,
    const StereoData *stereo_data,
    int available_data,
    const CableParameters *cable_params,
    RunMode run_mode,
    FusionData *fusion_result,
    ExtendedFusionData *extended_result
);

/**
 * @brief 计算冰生长率 - 从simulation.c迁移过来的增强版本
 */
float calculate_ice_growth_rate_ex(float temperature, float humidity, float wind_speed);

/**
 * @brief 计算运行时冰厚度 - 从simulation.c迁移过来的增强版本
 */
float calculate_runtime_ice_thickness_ex(float sensor_thickness, float visual_thickness, 
                                      float temperature, bool use_correction);

/**
 * @brief 使用传感器数据和视觉数据计算融合冰厚度
 */
float calculate_fusion_ice_thickness(SensorData *sensor_data, VisualIceData *visual_data);

#endif /* DATA_FUSION_H */ 